package com.aeoj.clientmanagement.controller;

import com.aeoj.clientmanagement.constant.PkConstant;
import com.aeoj.clientmanagement.domain.user.SysUser;
import com.aeoj.clientmanagement.domain.userscore.UserScore;
import com.aeoj.clientmanagement.domain.response.R;
import com.aeoj.clientmanagement.domain.user.vo.SysUserVO;
import com.aeoj.clientmanagement.domain.userscore.dto.RankingListDTO;
import com.aeoj.clientmanagement.domain.userscore.dto.UserScoreDTO;
import com.aeoj.clientmanagement.domain.userscore.vo.UserScoreVO;
import com.aeoj.clientmanagement.enums.userscore.RankEnum;
import com.aeoj.clientmanagement.schedule.RankSchedule;
import com.aeoj.clientmanagement.service.SysUserService;
import com.aeoj.clientmanagement.service.UserScoreService;
import com.aeoj.clientmanagement.utils.user.UserUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * UserScoreController
 * author: ZSM
 * time: 2025-04-23 12:50
 */
@RestController
@RequestMapping("/client/score")
@Slf4j
public class UserScoreController {
    @Resource
    private UserScoreService userScoreService;
    @Resource
    private RankSchedule rankSchedule;
    @Resource
    private SysUserService sysUserService;

    /**
     * 获取用户积分信息
     * @param request
     * @return
     */
    @GetMapping("get")
    public R getUserScore(HttpServletRequest request) {
        SysUserVO loginUser = UserUtils.getLoginUser(request);

        return R.ok(userScoreService.getUserScoreByUserId(loginUser.getUserId()));
    }

    /**
     * 获取排行榜
     * @param dto
     * @param request
     * @return
     */
    @GetMapping("ranking")
    public R getRanking(RankingListDTO dto, HttpServletRequest request) {
        SysUserVO loginUser = UserUtils.getLoginUser(request);

        Integer pageNum = dto.getPageNum();
        Integer pageSize = dto.getPageSize();
        Page<UserScoreVO> userScoreVOPage = new Page<>();
        Page<UserScore> page = new Page<>(pageNum, pageSize);

        List<UserScoreVO> list = userScoreService.listRankingByRedis(pageNum, pageSize);
        if (list == null || list.isEmpty()) {
            log.info("缓存失效");
            List<UserScoreDTO> userScoreDTOList = userScoreService.listRanking(pageNum, pageSize);

            List<UserScoreVO> res = new ArrayList<>();
            userScoreDTOList.forEach(x -> res.add(UserScoreVO.toUserScoreVO(x)));

            userScoreVOPage.setRecords(res);
            userScoreVOPage.setTotal(page.getTotal());
            new Thread(() -> rankSchedule.refreshRanking()).start();
        }
        else {
            userScoreVOPage.setRecords(list);
            userScoreVOPage.setTotal(list.size());
        }
        return R.ok(userScoreVOPage);
    }

    /**
     * 更新积分信息
     * @param request
     * @return
     */
    @PostMapping("update")
    public R updateUserScore(@RequestBody UserScoreDTO dto, HttpServletRequest request) {
        UserUtils.getLoginUser(request);
        UserScore userScore = userScoreService.getById(dto.getId());
        if (userScore == null) {
            return R.error("用户积分不存在");
        }

        if (dto.getScore() != null)
            userScore.setScore(dto.getScore());
        if (dto.getDescription() != null)
            userScore.setDescription(dto.getDescription());
        if (dto.getTotalMatches() != null)
            userScore.setTotalMatches(dto.getTotalMatches());
        if (dto.getWinMatches() != null)
            userScore.setWinMatches(dto.getWinMatches());
        if (dto.getLoseMatches() != null)
            userScore.setLoseMatches(dto.getLoseMatches());

        RankEnum rank = RankEnum.getByScore(userScore.getScore());
        userScore.setRankName(rank.getCode());

        boolean update = userScoreService.updateById(userScore);
        if (!update) {
            return R.error("更新失败");
        }

        return R.ok();
    }
}
